/*
-----------------------------------------------------------------------------
This source file is part of SapphireEngine

SapphireEngine is a Framework for Turn Based Strategy games.
For more information see http://code.google.com/p/sapphire-engine/

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

-----------------------------------------------------------------------------
*/
#ifndef _GAME_FACTOR_H
#define _GAME_FACTOR_H

#include "SapphirePrerequisites.h"

namespace SapphireEngine
{
	namespace Core
	{
		class GameFactor
		{
		public:
			GameFactor(const StringSet* factorTypes)
			{
				for (StringSetConstIterator itr = factorTypes->begin(); itr != factorTypes->end();itr++)
					mFactor.insert(GameFactorMapItem(*itr,0));
			}
			void setByType(Ogre::String factorType, long val)
			{
				GameFactorMapIterator itr = mFactor.find(factorType);
				itr->second = val;
			}
			long getByType(Ogre::String factorType)
			{
				return mFactor.find(factorType)->second;
			}

			void clearVals()
			{
				for (GameFactorMapIterator itr=mFactor.begin(); itr != mFactor.end(); itr++)
					itr->second=0;
			}

			//operators
			GameFactor &operator= (const GameFactor &factor)
			{
				mFactor.clear();
				mFactor.insert(factor.mFactor.begin(),factor.mFactor.end());
				return *this;
			}
			GameFactor operator+ (const GameFactor &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					tmpFactor.mFactor.find(itr->first)->second += itr->second;
				return tmpFactor;
			}
			GameFactor operator+ (const long &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapIterator itr=tmpFactor.mFactor.begin(); itr != tmpFactor.mFactor.end(); itr++)
					itr->second += factor;
				return tmpFactor;
			}
			void operator+= (const GameFactor &factor)
			{
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					mFactor.find(itr->first)->second += itr->second;
			}
			void operator+= (const long &factor)
			{
				for (GameFactorMapIterator itr=mFactor.begin(); itr != mFactor.end(); itr++)
					itr->second += factor;
			}
			GameFactor operator- (const GameFactor &factor)
			{
				GameFactor tmpFactor=*this;
				GameFactorMapIterator tmpItr;
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
				{
					tmpItr = tmpFactor.mFactor.find(itr->first);
					if (tmpItr->second > itr->second)
						tmpItr->second -= itr->second;
					else
						tmpItr->second = 0;
				}
				return tmpFactor;
			}
			GameFactor operator- (const long &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapIterator itr=tmpFactor.mFactor.begin(); itr != tmpFactor.mFactor.end(); itr++)
				{
					if(itr->second > factor)
						itr->second -= factor;
					else
						itr->second = 0;
				}
				return tmpFactor;
			}
			void operator-= (const GameFactor &factor)
			{
				GameFactorMapIterator tmpItr;
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
				{
					tmpItr = mFactor.find(itr->first);
					if (tmpItr->second > itr->second)
						tmpItr->second -= itr->second;
					else
						tmpItr->second = 0;
				}
			}
			void operator-= (const long &factor)
			{
				for (GameFactorMapIterator itr=mFactor.begin(); itr != mFactor.end(); itr++)
				{
					if(itr->second > factor)
						itr->second -= factor;
					else
						itr->second = 0;
				}
			}
			GameFactor operator* (const GameFactor &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					tmpFactor.mFactor.find(itr->first)->second *= itr->second;
				return tmpFactor;
			}
			GameFactor operator* (const long &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapIterator itr=tmpFactor.mFactor.begin(); itr != tmpFactor.mFactor.end(); itr++)
					itr->second *= factor;
				return tmpFactor;
			}
			void operator*= (const GameFactor &factor)
			{
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					mFactor.find(itr->first)->second *= itr->second;
			}
			void operator*= (const long &factor)
			{
				for (GameFactorMapIterator itr=mFactor.begin(); itr != mFactor.end(); itr++)
					itr->second *= factor;
			}
			GameFactor operator/ (const GameFactor &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					tmpFactor.mFactor.find(itr->first)->second *= itr->second;
				return tmpFactor;
			}
			GameFactor operator/ (const long &factor)
			{
				GameFactor tmpFactor=*this;
				for (GameFactorMapIterator itr=tmpFactor.mFactor.begin(); itr != tmpFactor.mFactor.end(); itr++)
					itr->second /= factor;
				return tmpFactor;
			}
			void operator/= (const GameFactor &factor)
			{
				for (GameFactorMapConstIterator itr=factor.mFactor.begin(); itr != factor.mFactor.end(); itr++)
					mFactor.find(itr->first)->second /= itr->second;
			}
			void operator/= (const long &factor)
			{
				for (GameFactorMapIterator itr=mFactor.begin(); itr != mFactor.end(); itr++)
					itr->second /= factor;
			}
		protected:
			GameFactorMap mFactor;
		};
	}
}

#endif